<?php

namespace App\Services\Admin;

use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Auth;
use Tymon\JWTAuth\Facades\JWTAuth;
use App\Models\User;
use App\Services\Service;
use Tymon\JWTAuth\Exceptions\JWTException;
use Tymon\JWTAuth\Exceptions\TokenExpiredException;
use Tymon\JWTAuth\Exceptions\TokenInvalidException;


class AuthService extends Service
{

    public static function init(): array
    {
        $result = User::create([
            'username' => 'admin',
            'password' => Hash::make('123456'), // Bcrypt 加密
            'nickname' => '系统管理员',
            'avatar'   => 'https://foruda.gitee.com/images/1723603502796844527/03cdca2a_716974.gif',
        ]);

        return [
            'id' => $result->id
        ];
    }

    public static function login(array $data)
    {
        $accessToken = Auth::attempt([
            'username' => $data['username'],
            'password' => $data['password']
        ]);

        $user = Auth::user();

        // 生成刷新令牌（自定义过期时间和类型）
        $refreshToken = JWTAuth::claims([
            'type' => 'refresh', // 标记为刷新令牌
            'exp' => now()->addMinutes(config('jwt.refresh_ttl'))->timestamp // 单独的过期时间
        ])->fromUser($user);

        return [
            'accessToken'      => $accessToken,
            'refreshToken' => $refreshToken,
            'tokenType'        => 'Bearer',
            'expiresIn'        => JWTAuth::factory()->getTTL() * 60,
            'refreshExpiresIn' => config('jwt.refresh_ttl') * 60,
        ];
    }

    public static function refreshToken(string $oldRefreshToken): array
    {

        $resultErrorData = [
            'status' => 401,
            'data'   => []
        ];

        try {
            JWTAuth::setToken($oldRefreshToken);
            $payload = JWTAuth::getPayload();
            if ($payload->get('type') !== 'refresh') {

                $resultErrorData['data'] = [
                    'code' => 'A0231',
                    'msg' => '无效的刷新令牌类型'
                ];

                return $resultErrorData;
            }

            // 获取当前用户（后续用于生成新令牌）
            $user = JWTAuth::authenticate();
            if (!$user) {

                $resultErrorData['data'] = [
                    'code' => 'A0231',
                    'msg' => '刷新令牌对应的用户不存在'
                ];

                return $resultErrorData;
            }

            // 生成新 Access Token
            $newAccessToken = JWTAuth::refresh();
            // 生成新 Refresh Token（设置类型为 refresh + 长期有效期）
            $newRefreshToken = JWTAuth::claims([
                'type' => 'refresh', // 标记为刷新令牌
                'exp' => now()->addMinutes(config('jwt.refresh_ttl'))->timestamp // 单独的过期时间
            ])->fromUser($user);

            // 拉黑旧 Refresh Token
            JWTAuth::setToken($oldRefreshToken)->invalidate();

            // 返回新的 Access Token 和 Refresh Token
            return [
                'status' => 200,
                'data'   => [
                    'accessToken'      => $newAccessToken,
                    'refreshToken'     => $newRefreshToken, // 新 Refresh Token
                    'tokenType'        => 'Bearer',
                    'expiresIn'        => config('jwt.ttl') * 60, // 新 Access Token 过期时间
                    'refreshExpiresIn' => config('jwt.refresh_ttl') * 60 // 新 Refresh Token 过期时间
                ]
            ];
        } catch (TokenExpiredException $e) {

            $resultErrorData['data'] = [
                'code' => 'A0231',
                'msg'  => '刷新令牌已过期，请重新登录'
            ];

            return $resultErrorData;
        } catch (TokenInvalidException $e) {

            $resultErrorData['data'] = [
                'code' => 'A0231',
                'msg'  => '无效的刷新令牌'
            ];

            return $resultErrorData;
        } catch (JWTException $e) {

            $resultErrorData['data'] = [
                'code'    => 'A0231',
                'message' => '刷新令牌验证失败'
            ];

            return $resultErrorData;
        }
    }
}
